home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471323519
Publication Date: 11/01/98

Search this book:
 
Previous Table of Contents Next


Encapsulate with Controls

ActiveX controls are a lot like classes. Both provide public methods, events, and property procedures to interact with the outside program. In many ways, a class is simply a control with no visible interface.

Even the simplest Visual Basic program uses controls, so every Visual Basic programmer is familiar with them. While some programmers may not have mastered classes and object-oriented programming, they all know how to use controls. Take advantage of that preexisting experience by building ActiveX controls to encapsulate behavior.

Controls have the advantage that you can distribute them in binary form. That means you can sometimes upgrade a control without recompiling an application. As long as you do not change the control’s public interface, you can upgrade it quickly and easily without rebuilding the rest of the application.

You can also allow other developers to use only the compiled OCX version of the control. That hides more detail from them so they are less likely to write code that relies on the control’s internals. If they cannot see the source code, they cannot easily tie their code to the control’s internal idiosyncrasies.

Encapsulate with Modules

Many programmers overlook the fact that they can use modules to encapsulate data and functionality. A module can contain private variables, data structures, and routines that it needs but that are not needed by other parts of the program. To maximize encapsulation, as many of the module’s details as possible should be private.

For example, a work assignment program might keep a list of items sorted in priority order. The CreateJob subroutine creates a new job and adds it to the list. Subroutine GetNextJob fills in a user-defined data structure to describe the next job that must be worked.

These subroutines could be placed inside a module. The list of jobs is stored using variables private to that module. All the rest of the program sees are the CreateJob and GetNextJob subroutines. The complexity of the job list is hidden from the main program. The jobs could be stored in an array, linked list, priority queue, tree, or some other data structure.

Encapsulating the details of the job list within the module makes it easier to think about the rest of the program. While you concentrate on other parts of the code, you can ignore the job list internals.

Encapsulating the job list also prevents the rest of the program from relying on the particular implementation of the list’s internals. If you later find a bug in the way the list is stored, you can fix it without breaking the rest of the program.

Group related routines in the same module so they are easy to find. Do not include unrelated routines in a module. This decreases the encapsulation provided by the module because the unrelated routine can access the module’s private data. One module should contain all of the routines related to one topic and nothing more.

Encapsulate with Subroutines

If you use the same code more than once, place it in a subroutine. By calling the routine, you can reuse the code without having to write several copies. A less-obvious benefit of subroutines is that you only need to debug, test, and maintain one copy of the code. If duplicate code is replaced with a subroutine, you do not need to worry about keeping the separate copies synchronized when you make changes.

One opportunity for reducing code duplication that is often overlooked is in form management code. If you perform the same task for many forms, write a subroutine in a .BAS module to do it. Make the routine take the form it should manipulate as a parameter. For example, the following routines save and restore a form’s size and position in the system registry.

‘ Save the form’s size and position.
Public Sub SaveFormPosition(frm As Form)
    SaveSetting “MyProgram”, “Layout”, frm.Name & “ Left”, frm.Left
    SaveSetting “MyProgram”, “Layout”, frm.Name & “ Top”, frm.Top
    SaveSetting “MyProgram”, “Layout”, frm.Name & “ Width”, frm.Width
    SaveSetting “MyProgram”, “Layout”, frm.Name & “ Height”, frm.Height
End Sub

‘ Reload the form’s size and position.
Public Sub LoadFormPosition(frm As Form)
Dim l As Single
Dim t As Single
Dim w As Single
Dim h As Single

    ‘ Get the settings.
    l = GetSetting(“MyProgram”, “Layout”, frm.Name & “ Left”, _
        Format$(frm.Left))
    t = GetSetting(“MyProgram”, “Layout”, frm.Name & “ Top”, _
        Format$(frm.Top))
    w = GetSetting(“MyProgram”, “Layout”, frm.Name & “ Width”, _
        Format$(frm.Width))
    h = GetSetting(“MyProgram”, “Layout”, frm.Name & “ Height”, _
        Format$(frm.Height))

    ‘ Size and position the form.
     frm.Move l, t, w, h
End Sub

Instead of placing code to save and load these values in each form, you can make the forms invoke these subroutines. A form could use these routines to set and save its size and position when it is loaded and unloaded, as shown in the following code:

Private Sub Form_Load()
    LoadFormPosition Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
    SaveFormPosition Me
End Sub

Encapsulate Errors

When a routine fails during design, it should stop to alert developers to the problem so they can fix it. In the final compiled version, the program must continue running even if an unexpected error occurs. This can be very difficult for some programs. If an operation completes only partially, it may leave data in an ambiguous state from which it is hard to continue.

To minimize this kind of problem, routines should encapsulate their errors. They should hide the effects of their errors from calling routines. When a routine fails, it should undo any changes it has made to global data structures. Then the calling routine can continue operating without needing to know how much the routine accomplished before it failed.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.